home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / libg_261.zip / libg_261 / libg++ / src / Obstack.cc < prev    next >
C/C++ Source or Header  |  1994-03-14  |  3KB  |  126 lines

  1. /* 
  2. Copyright (C) 1988 Free Software Foundation
  3.     written by Doug Lea (dl@rocky.oswego.edu)
  4.  
  5. This file is part of the GNU C++ Library.  This library is free
  6. software; you can redistribute it and/or modify it under the terms of
  7. the GNU Library General Public License as published by the Free
  8. Software Foundation; either version 2 of the License, or (at your
  9. option) any later version.  This library is distributed in the hope
  10. that it will be useful, but WITHOUT ANY WARRANTY; without even the
  11. implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  12. PURPOSE.  See the GNU Library General Public License for more details.
  13. You should have received a copy of the GNU Library General Public
  14. License along with this library; if not, write to the Free Software
  15. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17.  
  18. #ifdef __GNUG__
  19. #pragma implementation
  20. #endif
  21. #include <limits.h>
  22. #include <builtin.h>
  23. #include <Obstack.h>
  24.  
  25. /* We use subtraction of (char *)0 instead of casting to int
  26.    because on word-addressable machines a simple cast to int
  27.    may ignore the byte-within-word field of the pointer.  */
  28.  
  29. #ifndef __PTR_TO_INT
  30. #define __PTR_TO_INT(P) ((P) - (char *)0)
  31. #endif
  32.  
  33. #ifndef __INT_TO_PTR
  34. #define __INT_TO_PTR(P) ((P) + (char *)0)
  35. #endif
  36.  
  37. Obstack::Obstack(int size, int alignment)
  38. {
  39.   alignmentmask = alignment - 1;
  40.   chunksize = size;
  41.   chunk = 0;
  42.   nextfree = objectbase = 0;
  43.   chunklimit = 0;
  44. }
  45.  
  46. void Obstack::_free(void* obj)
  47. {
  48.   _obstack_chunk*  lp;
  49.   _obstack_chunk*  plp;
  50.  
  51.   lp = chunk;
  52.   while (lp != 0 && ((void*)lp > obj || (void*)(lp)->limit < obj))
  53.   {
  54.     plp = lp -> prev;
  55.     delete [] (char*)lp;
  56.     lp = plp;
  57.   }
  58.   if (lp)
  59.   {
  60.     objectbase = nextfree = (char *)(obj);
  61.     chunklimit = lp->limit;
  62.     chunk = lp;
  63.   }
  64.   else if (obj != 0)
  65.     (*lib_error_handler)("Obstack", "deletion of nonexistent obj");
  66. }
  67.  
  68. void Obstack::newchunk(int size)
  69. {
  70.   _obstack_chunk*    old_chunk = chunk;
  71.   _obstack_chunk*    new_chunk;
  72.   long    new_size;
  73.   int obj_size = nextfree - objectbase;
  74.  
  75.   new_size = (obj_size + size) << 1;
  76.   if (new_size < chunksize)
  77.     new_size = chunksize;
  78.  
  79.   new_chunk = chunk = (_obstack_chunk*)(new char[new_size]);
  80.   new_chunk->prev = old_chunk;
  81.   new_chunk->limit = chunklimit = (char *) new_chunk + new_size;
  82.  
  83.   memcpy((void*)new_chunk->contents, (void*)objectbase, obj_size);
  84.   objectbase = new_chunk->contents;
  85.   nextfree = objectbase + obj_size;
  86. }
  87.  
  88. void* Obstack::finish()
  89. {
  90.   void* value = (void*) objectbase;
  91.   nextfree = __INT_TO_PTR (__PTR_TO_INT (nextfree + alignmentmask)
  92.                & ~alignmentmask);
  93.   if (nextfree - (char*)chunk > chunklimit - (char*)chunk)
  94.     nextfree = chunklimit;
  95.   objectbase = nextfree;
  96.   return value;
  97. }
  98.  
  99. int Obstack::contains(void* obj) // true if obj somewhere in Obstack
  100. {
  101.   for (_obstack_chunk* ch = chunk; 
  102.        ch != 0 && (obj < (void*)ch || obj >= (void*)(ch->limit)); 
  103.        ch = ch->prev);
  104.  
  105.   return ch != 0;
  106. }
  107.          
  108. int Obstack::OK()
  109. {
  110.   int v = chunksize > 0;        // valid size
  111.   v &= alignmentmask != 0;      // and alignment
  112.   v &= chunk != 0;
  113.   v &= objectbase >= chunk->contents;
  114.   v &= nextfree >= objectbase;
  115.   v &= nextfree <= chunklimit;
  116.   v &= chunklimit == chunk->limit;
  117.   _obstack_chunk* p = chunk;
  118.   // allow lots of chances to find bottom!
  119.   long x = LONG_MAX;
  120.   while (p != 0 && x != 0) { --x; p = p->prev; }
  121.   v &= x > 0;
  122.   if (!v) 
  123.     (*lib_error_handler)("Obstack", "invariant failure");
  124.   return v;
  125. }
  126.